<?php

use Symfony\Component\HttpFoundation\Response;
use Yansongda\Pay\Contracts\GatewayApplicationInterface;
use Yansongda\Pay\Exceptions\InvalidGatewayException;
use Yansongda\Pay\Pay as PaySDK;

class Pay extends M_Controller
{
    protected $payConfig;
    protected $payGateways = [];

    /**
     * 构造函数
     */
    public function __construct()
    {
        parent::__construct();
        $this->config->load('pay', true);
        $this->payConfig = $this->config->item('pay');
    }

    public function index()
    {
        $id = (int)$this->input->get('id');
        $pay = $this->models('system/pay')->get($id);
        if ($pay) {

        } else {

        }
        $this->render(array());
    }

    /**
     * 支付统一下单
     */
    public function initiate()
    {
        $field = $this->input->post();
        if ((int)$this->uid < 1) {
            apiSuccess(-4001, '未登录');
        }
        $id = (int)decrypt($field['id'], 'mutaoinc');
        $type = $field['type'];
        $gateway = $field['gateway'];
        if (!$id || !$type || !$gateway) {
            $this->msg(0, '参数错误');
        } elseif (!$data = $this->models('system/pay')->getItem($id)) {
            $this->msg(0, '记录不存在');
        } elseif ($data['uid'] && $data['uid'] != $this->uid) {
            $this->msg(0, '没有权限');
        } elseif ($data['status'] != 0) {
            $this->msg(0, '订单已结束');
        } elseif (in_array($type, $data['disabled_pays'])) {
            $this->msg(0, '不支持此支付方式');
        } else {
            ### 购买首发藏品的时候要查看订单是否过期
            switch ($field['order_type']) {
                case 'favorite':
                    $queue = $this->models('favorite')->getQueue($data['order']);
                    if ((int)$queue['end_time'] < time()) {
                        $this->models('favorite')->operateLock($queue['cid'], 0);
                        apiSuccess(0, '订单已结束请重新下单');
                    }
                    break;
                default:
                    break;
            }
            $orderPrice = abs($data['value']);
            if ($type == 'balance') {
                /*$password = $this->input->post('password');
                $pay = $this->models('member')->memberPayPsd($this->uid);
                if (empty($pay)) {
                    apiSuccess(0, '密码不存在');
                }
                if (md5(md5($password) . $pay['salt'] . md5($password)) <> $pay['password']) {
                    apiSuccess(0, '支付密码错误');
                }*/
                if ($this->member['money'] < $orderPrice) {
                    apiSuccess(0, '余额不足');
                } else {
                    $this->db->trans_start();
                    $this->models('member')->modify_money($this->uid, -$orderPrice);
                    $this->models('system/pay')->paySuccess('balance', $data);
                    $this->db->trans_complete();
                    apiSuccess(1, 'success', ['payed' => 1, 'type' => 'balance']);
                }
            } else {
                try {
                    $gatewayInstance = $this->getGateway($type);
                    $outTradeNo = 'P-' . date('ymdHis', $data['inputtime'])
                        . '-' . str_pad($data['id'], '8', 0, STR_PAD_LEFT);
                    $title = SITE_NAME . '-' . ($data['note'] ?: '消费');
                    $configBiz = ['out_trade_no' => $outTradeNo];
                    switch ($type) {
                        case 'wechat':
                            $configBiz = [
                                    'total_fee' => $orderPrice * 100,
                                    'body' => $title,
                                    'spbill_create_ip' => $_SERVER['REMOTE_ADDR']
                                ] + $configBiz;
                            if (in_array($gateway, ['mp', 'miniapp'])) {
                                $openID = $this->models('member')->wxInfo($data['uid'], 'openid');
                                if (isset($openID)) {
                                    $configBiz['openid'] = $openID;
                                } else {
                                    apiSuccess(40003, '无法获取openid');
                                }
                            }
                            break;
                        case 'alipay':
                            $configBiz = [
                                    'total_amount' => $orderPrice,
                                    'subject' => $title
                                ] + $configBiz;
                            if ($gateway == 'web') {
                                if (isset($_GET['qr_mode']) && is_numeric($_GET['qr_mode'])) {
                                    $configBiz['qr_pay_mode'] = $_GET['qr_mode'];
                                    if ($_GET['qr_mode'] == 4 && isset($_GET['qr_size']) && is_numeric($_GET['qr_size'])) {
                                        $configBiz['qrcode_width'] = $_GET['qr_size'];
                                    }
                                }
                            }
                            break;
                        default:
                            throw new InvalidGatewayException("Driver [$type]'s is unsupported.");
                    }
                    $result = $gatewayInstance->pay($gateway, $configBiz);
                    if ($result instanceof Response) {
                        $result->send();
                    } else {
                        $this->msg(1, ['payed' => 0, 'payment' => $result->all()], 'success');
                    }
                } catch (InvalidGatewayException $e) {
                    $this->msg(0, '支付方式不支持:' . $e->getMessage());
                } catch (Exception $e) {
                    $this->msg(0, '支付出错:' . $e->getMessage());
                }
            }
        }
    }

    public function pay_status()
    {
        $id = (int)$_GET['id'];
        if (!$id) {
            $this->msg(0, '参数错误');
        } elseif (!$data = $this->models('system/pay')->getItem($id)) {
            $this->msg(0, '记录不存在');
        } else {
            $this->msg(1, ['status' => (int)$data['status']]);
        }
    }

    public function pay_return()
    {
        echo $this->getGateway($_GET['type'])->verify($_SERVER['QUERY_STRING']);
    }

    public function notify()
    {
        $gatewayInstance = $this->getGateway($_GET['type']);
        switch ($_GET['type']) {
            case 'alipay':
                $request = $_REQUEST;
                if (
                    $gatewayInstance->verify($request)
                    && in_array($request['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED'])
                ) {
                    $out_trade_no = $request['out_trade_no'];
                    $money = $request['total_amount'];
                }
                break;
            case 'wechat':
                if ($request = $gatewayInstance->verify(file_get_contents('php://input') ?: '<xml></xml>')) {
                    $out_trade_no = $request['out_trade_no'];
                    $money = $request['total_fee'] / 100;
                }
        }
        if (isset($out_trade_no)) {
            $payid = (int)substr(strrchr($out_trade_no, '-'), 1);
            $paylog = $this->models('system/pay')->getItem($payid);
            if ($paylog && $paylog['status'] == 0 && abs($paylog['value']) == $money) {
                $this->models('system/pay')->paySuccess($_GET['type'], $paylog, $request);
            }
        }
        echo 'success';
    }

    /**
     * @param string $name
     * @return GatewayApplicationInterface
     * @throws InvalidGatewayException
     */
    protected function getGateway(string $name): GatewayApplicationInterface
    {
        if (isset($this->payConfig[$name])) {
            return $this->payGateways[$name] ?? $this->payGateways[$name]
                    = PaySDK::$name($this->payConfig[$name] + ($this->payConfig['global'] ?? []));
        }
        throw new InvalidGatewayException("Gateway [$name] Not Exists");
    }

    /**
     * 退款消息通知
     */
    public function refundOrder()
    {
        return file_put_contents(__DIR__ . '/a.txt', json_encode($_GET));
    }
}
